import echarts from 'echarts/lib/echarts';
// 引入折线图
import 'echarts/lib/chart/line';
// 引入柱状图
import 'echarts/lib/chart/bar';
// 引入提示框和标题组件
import 'echarts/lib/component/title';
import 'echarts/lib/component/legendScroll';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/toolbox';
import 'echarts/lib/component/grid';
import 'echarts/lib/chart/custom';
import 'echarts/lib/component/dataZoom';

import { getQueryString, getMap, is_in_array_kv, is_in_array } from "../utils";
console.log("echarts版本:" + echarts.version)

// 获得x轴数组数据
// array:接口数组数据
function getXAxisList(array, field) {
    if (!$.isArray(array)) return [];
    var rarray = [];
    for (var i = 0; i < array.length; i++) {
        if (array[i] && array[i][field]) {
            rarray.push(array[i][field])
        }
    }
    if (getQueryString("flag") == "true") console.log("XAxisList", rarray);
    return rarray;
}

// 获得列名字数组数据
// yconfig：y轴配置定义
function getLegend(yconfig) {
    if (!$.isArray(yconfig)) return [];
    var rarray = []
    for (var i = 0; i < yconfig.length; i++) {
        var item = yconfig[i];
        if (item) { rarray.push(item["showname"] ? item["showname"] : item["name"]); }
    }
    if (getQueryString("flag") == "true") console.log("legend", rarray);
    return rarray;
}

// 获得y抽数组数据
// array:接口数组数据
// yconfig：y轴配置定义
function getYSeriesList(array, yconfig) {
    // debugger
    if (!$.isArray(array)) return [];
    if (!$.isArray(yconfig)) return [];
    var rarray = [];
    // 找出所有系列series，并清空其data
    for (var i = 0; i < yconfig.length; i++) {
        var yitem = yconfig[i]; //每条列配置数据
        rarray.push({
            name: yitem["showname"] ? yitem["showname"] : yitem["name"],
            type: yitem["type"] ? yitem["type"] : "line",
            data: [],
            // markLine: {
            //     data: [
            //         { type: 'average', name: '平均值' }
            //     ]
            // }
        })
    }
    for (var i = 0; i < array.length; i++) {
        var item = array[i];    //每条接口数据
        if (item) {
            for (var j = 0; j < rarray.length; j++) {
                var yitem = rarray[j]; //每条列配置数据
                var ycitem = yconfig[j];
                if (ycitem && ycitem["name"] && item[ycitem["name"]] !== undefined) {
                    yitem["data"].push(item[ycitem["name"]])
                }
                // 已存在的系列保留，补充值为0
                // else{
                //     yitem["data"].push(0);
                // }
                // 已存在的系统删除 保证系列由传入的数据决定
                else {
                    rarray.removeByIndex(j);
                }
            }
        }
    }
    if (getQueryString("flag") == "true") console.log("YSeriesList", rarray);
    return rarray;
}

// 渲染图
export function RenderChart(config) {
    this.chart = null;  //echart实际实例
    this.config = config;   //初始化传递的config配置对象
    this.option = null;     //此函数getCustomOption组合创建的配置对象
    this.init = () => {
        if (!this.config || JSON.stringify(this.config) == "{}") return;
        var id = this.config.id;
        this.chart = echarts.init(document.getElementById(id));
        this.setConfig();
        return this;
    }

    // 获得配置
    this.getCustomOption = (config) => {
        // 指定图表的配置项和数据
        return {
            title: {
                text: config && config["title"] ? config["title"] : this.config["title"] ? this.config["title"] : "",
                subtext: ''
            },
            tooltip: { show: true, trigger: 'axis' },
            toolbox: {
                show: true, //是否显示工具栏组件
                //工具栏 icon 的布局朝向   horizontal(default) vertical
                orient: config && config["orient"] ? config["orient"] : this.config["orient"] ? this.config["orient"] : "horizontal",
                feature: {
                    dataView: { readOnly: false },
                    magicType: { type: ['line', 'bar'] },
                    restore: {},
                    saveAsImage: {}
                }
            },
            legend: {
                top: 40,
                orient: "horizontal",
                position: "bottom",
                type: "scroll",
                data: config && $.isArray(config["series"]) ? getLegend(config["series"]) : []
            },
            // grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
            // 声明一个 X 轴，类目轴（category）。默认情况下，类目轴对应到 dataset 第一列。
            xAxis: {
                type: 'category',
                // boundaryGap: false,
                boundaryGap: true,
                axisPointer: { type: 'shadow' },
                data: config && $.isArray(config["xAxis"]) ? config["xAxis"] : this.config["xAxis"] ? this.config["xAxis"] : []
            },
            // 声明一个 Y 轴，数值轴。
            yAxis: {
                type: 'value',
                // scale: true,
                // name: 'xxx',
                // boundaryGap: [0.2, 0.2]
            },
            // 声明多个 bar 系列，默认情况下，每个系列会自动对应到 dataset 的每一列。
            series: config && $.isArray(config["series"]) ? config["series"] : this.config["series"] ? this.config["series"] : [],
            // dataset: {
            // 提供一份数据。
            //     source: [
            //         ['product', '2015', '2016', '2017'],
            //         ['Matcha Latte', 43.3, 85.8, 93.7],
            //         ['Milk Tea', 83.1, 73.4, 55.1],
            //         ['Cheese Cocoa', 86.4, 65.2, 82.5],
            //         ['Walnut Brownie', 72.4, 53.9, 39.1]
            //     ]
            // },
            // dataset: {
            // 这里指定了维度名的顺序，从而可以利用默认的维度到坐标轴的映射。
            // 如果不指定 dimensions，也可以通过指定 series.encode 完成映射，参见后文。
            //     dimensions: ['product', '2015', '2016', '2017'],
            //     source: [
            //         {product: 'Matcha Latte', '2015': 43.3, '2016': 85.8, '2017': 93.7},
            //         {product: 'Milk Tea', '2015': 83.1, '2016': 73.4, '2017': 55.1},
            //         {product: 'Cheese Cocoa', '2015': 86.4, '2016': 65.2, '2017': 82.5},
            //         {product: 'Walnut Brownie', '2015': 72.4, '2016': 53.9, '2017': 39.1}
            //     ]
            // },
            // 用于区域缩放
            // 数据过滤：filterMode: 'filter' 的效果是：过滤数据后使另外的轴也能自动适应当前数据的范围。     
            // 数据窗口范围：start: 20,end:80  --> dataZoomY 的 start: 20, end: 80 表示 yAxis.min ~ yAxis.max 的 20% 到 80%。
            dataZoom1: [
                {
                    type: 'slider',
                    show: true, //[ default: true ] 是否显示 组件。如果设置为 false，不会显示，但是数据过滤的功能还存在。
                    xAxisIndex: [0], //[ default: null ] 设置 dataZoom-slider 组件控制的 x轴. 是 number 表示控制一个轴，如果是 Array 表示控制多个轴。
                    start: 50,
                    end: 100,
                    // left: 93%, //[ default: 'auto' ] dataZoom-slider组件离容器左侧的距离。
                    // showDataShadow: false,  //[ default: 'auto' ] 是否在 dataZoom-silder 组件中显示数据阴影。数据阴影可以简单地反应数据走势。
                    // handleSize: 1, //[ default: '100%' ] 控制手柄的尺寸，可以是像素大小，也可以是相对于 dataZoom 组件宽度的百分比，默认跟 dataZoom 宽度相同。
                },
                {
                    type: 'slider',
                    show: true,
                    yAxisIndex: [0], //[ default: null ] 设置 dataZoom-slider 组件控制的 y轴. 是 number 表示控制一个轴，如果是 Array 表示控制多个轴。
                    // left: '93%',
                    start: 0,
                    end: 100
                },
                {
                    type: 'inside',
                    xAxisIndex: [0],
                    start: 50,
                    end: 100
                },
                {
                    type: 'inside',
                    yAxisIndex: [0],
                    start: 0,
                    end: 100
                }
            ],
        };
    }

    // 修改配置
    this.setConfig = (config) => {
        if (!this.chart) return;
        // this.chart.clear();
        var option = this.getCustomOption(config);
        this.chart.setOption(option, true);
        if (config) {
            if (config.series) this.config.series = config.series;
            if (config.xfield) this.config.xfield = config.xfield;
            // console.log(getMap(config.series, "name"))
        }
        this.option = option;
    }

    // 获得配置
    this.getConfig = () => {
        return this.option;
    }

    // 清除配置
    // this.clear = function(){
    //     this.chart.clear();
    // }

    // 删除某系列数据源
    // 参数为数组，则依次删除每系列，参数为字符串，则删除此系列
    this.deleteDataSourceBySeriesName = (param) => {
        var option = this.option;
        var fn = (seriesname) => {
            for (var i = 0; i < option.series.length; i++) {
                if (option.series[i].name == seriesname) {
                    option.series.removeByIndex(i);
                }
            }
            option.legend.data.removeByVal(seriesname);
            // this.setAndSaveOption(option);
            this.chart.setOption(option, true);
            this.option = $.extend(this.option, option);
        }
        if ($.isArray(param)) {
            for (var i = 0; i < param.length; i++) {
                if (typeof (param[i] == "string")) fn(param[i]);
            }
        }
        else if (typeof (param) == "string") {
            fn(param);
        }
    }

    // 清空数据源
    this.clearDataSource = () => {
        var option = this.option;
        for (var i = 0; i < option.series.length; i++) {
            option.series[i].data = [];
        }
        // this.setAndSaveOption(option);
        this.chart.setOption(option, true);
        this.option = $.extend(this.option, option);
    }

    // 设置数据源
    this.setDataSource = (array) => {
        // debugger
        if (!$.isArray(array)) return;
        if (!this.config) return;
        var newXAxis = getXAxisList(array, this.config.xfield); //tm
        var newSeries = getYSeriesList(array, this.config.series);
        var newLegend = getLegend(newSeries);
        console.log("setDataSource: ", newSeries, newLegend);
        this.clearDataSource();
        this.setConfig({
            xAxis: newXAxis,
            series: newSeries,
            legend: {
                data: newLegend
            }
        });
    }

    // array要追加的数组数据，shift是否删除掉同等数量的
    // [{ tm: getStringDate(), [array[0]]: parseFloat(array[1]) }]
    this.addDataSource_old = (array, shift) => {
        if (!$.isArray(array)) return;
        var option = this.option;
        var map = getMap(getYSeriesList(array, this.config.series), 'name');
        var addXAxis = getXAxisList(array, this.config.xfield); //tm
        // console.log("map",map);
        // console.log("addXAxis",addXAxis);
        option.xAxis.data = $.unique(option.xAxis.data.concat(addXAxis));
        // console.log(option.xAxis.data)
        // console.log(option.series)
        // 如果为true 添加多少个会从前面删除多少个
        if (shift) { option.xAxis.data.splice(0, addXAxis.length); }

        for (var i = 0; i < option.series.length; i++) {
            var itemdata = option.series[i].data ? option.series[i].data : [];
            var itemname = option.series[i].showname;
            option.series[i].data = itemdata.concat(map[itemname].data);
            // 如果为true 添加多少个会从前面删除多少个
            if (shift) {
                option.series[i].data.splice(0, map[itemname].data.length);
            }
        }
        // console.log("之后",option)
        this.chart.setOption({
            xAxis: option.xAxis,
            series: option.series,
        });
    }
    // array : [key:val] 针对具体数据传入 待删除
    this.addDataSource_old2 = (array) => {
        var option = this.option;
        var find = false;
        for (var i = 0; i < option.series.length; i++) {
            var itemdata = option.series[i].data ? option.series[i].data : [];
            var itemname = option.series[i].showname;
            if (itemname == array[0]) {
                find = true;    //已存在
                itemdata.push(array[1]);
            } else {
                itemdata.push(itemdata[itemdata.length - 1]);
            }
        }
        // if (!find) {
        //     var pushOne = { name: array[1], showname: array[1], type: 'line', data: [] };
        //     for (i = 0; i < option.xAxis.data.length; i++) { pushOne["data"].push(0); }
        //     option.series.push(pushOne)
        // }

        this.chart.setOption({
            series: option.series,
        });
    }

    // obj: { x: 6, data: { d: 1 } }
    // array: [{ x: 7, data: { a: 1 } }, { x: 8, data: { b: 1 } }, { x: 9, data: { c: 1 } }]
    this.addDataSource = (data) => {
        if (!data) return;
        var option = this.option;
        if ($.isArray(data)) {
            for (var i = 0; i < data.length; i++) {
                var item = data[i];
                this.addXThenPushSameDataOfSeries(item["x"], option.xAxis.data, option.series);
                this.correctOneDataOfSeries(item["x"], item["data"], option.xAxis.data, option.series);
            }
        }
        else if (typeof (data) == "object") {
            this.addXThenPushSameDataOfSeries(data["x"], option.xAxis.data, option.series);
            this.correctOneDataOfSeries(data["x"], data["data"], option.xAxis.data, option.series);
        }
    }

    // 每加一次x轴之后，就补充当前每列的最后一项数据为上一次的最后值（保证数据结构一致）
    this.addXThenPushSameDataOfSeries = (x, old_xAxis, old_series) => {
        // debugger
        var old_xAxis = old_xAxis;  //当前x轴数据
        var old_series = old_series; //当前y轴所有系列
        // x轴数据不同才增加
        if (!is_in_array(old_xAxis, x)) {
            old_xAxis.push(x); //去重添加
            if (old_series.length > 0) {
                for (var i = 0; i < old_series.length; i++) {
                    if (!old_series[i]["data"]) {
                        old_series[i]["data"] = [];
                        old_series[i]["data"].push(0);
                    }
                    else {
                        var data = old_series[i]["data"];
                        var lastData = data[data.length - 1];
                        data.push(lastData);
                    }
                }
            }
        }
        // 写一个函数 存储了此次的提交之后 再设置给实例的配置
        this.setAndSaveOption({
            xAxis: {
                data: old_xAxis
            },
            series: old_series,
            legend: {
                data: getLegend(old_series)
            }
        })
        console.log("addDataSource: ", old_series, getLegend(old_series));
    }

    // 修改每列的正确数据（存在就替换值，不存在就添加系列series）
    this.correctOneDataOfSeries = (x, obj, old_xAxis, old_series) => {
        // debugger
        var old_xAxis = old_xAxis;  //当前x轴数据
        var old_series = old_series; //当前y轴所有系列
        var index_x = is_in_array(old_xAxis, x, "rtindex");
        // 在x轴存在，数据替换
        if (index_x !== -1) {
            for (var k in obj) {
                var index_line = is_in_array_kv(old_series, "name", k, "rtindex");
                // 不存在 就 添加系列 且从添加的位置至之后都维持此值
                if (index_line === -1) {
                    var oneData = getNewZeroValSeries(old_xAxis);    // 创建一条有完整数据结构的系列
                    for (var i = index_x; i < oneData.length; i++) {
                        oneData.splice(i, 1, obj[k]);
                    }
                    old_series.push({ name: k, showname: k, data: oneData, type: "line" });
                }
                // 存在 就 替换系列
                else {
                    old_series[index_line]["data"].splice(index_x, 1, obj[k]);
                }
            }
        }
        // 在x轴不存在，数据新增在最后
        else {
            for (var k in obj) {
                var index_line = is_in_array_kv(old_series, "name", k, "rtindex");
                // 不存在 就 添加系列
                if (index_line === -1) {
                    var oneData = getNewZeroValSeries(old_xAxis);    // 创建一条有完整数据结构的系列
                    oneData.splice(oneData.length - 1, 1, obj[k]);
                    old_series.push({ name: k, data: oneData, type: "line" });
                }
                // 存在 就 替换系列
                else {
                    old_series[index_line]["data"].splice(old_series[index_line]["data"].length - 1, 1, obj[k]);
                }
            }
        }
        this.setAndSaveOption({
            series: old_series,
            legend: {
                data: getLegend(old_series)
            }
        })
    }

    // 创建一条有完整数据结构的系列
    this.getNewZeroValSeries = (old_xAxis) => {
        var old_xAxis = old_xAxis;  //当前x轴数据
        var rtArray = [];
        for (var i = 0; i < old_xAxis.length; i++) {
            rtArray.push(0);
        }
        return rtArray;
    }

    // 修改并存储配置
    this.setAndSaveOption = (option) => {
        if (!this.chart) return;
        this.chart.setOption(option);
        this.option = $.extend(this.option, option);
    }
}


// ————————————————————————————————————————————思路——————————————————————————————————————————————
// splice 可以完成删除,插入,替换操作
// 格式: 数组.splice(参数1, 参数2, 参数3);
// 参数1 表示:开始下标的位置
// 参数2 表示:截取的长度
// 参数3 表示:要插入的元素

// {a:5,b:3} 接口返回的数据  某列：其值  当前时间
// ||> x:string, series:[{name:a,data:[xx,xx,xx,5]},{name:b,data:[xx,xx,xx,3]}]
// ||> add

// 接口数据解析 转换识别的格式

// 添加数据源（x轴添加 y轴有就加值（其余加当前上一次的值） 没有就加series（x轴的长度每个置为0，最后一个为当前值，其余加当前上一次的值））  
//          每个series  每次x加一个时都把值加一
// 每次加一个x轴后 y轴的每个series都push一个最后拿到的值
// 遍历每个y轴series名字，如果为此次数据的key，则修改其最后一个值为此次数据的val
// 如果没有出现此名字，就push进series中一个对象，遍历x轴长度赋值为0，最后一个值为此次树的val

// 每加一次x轴之后，就补充当前每列的最后一项数据为上一次的最后值（保证数据结构一致）
function addXThenPushSameDataOfSeries(string, old_xAxis, old_series) {
    var old_xAxis = old_xAxis;  //当前x轴数据
    var old_series = old_series; //当前y轴所有系列
    old_xAxis.push(string);
    for (var i = 0; i < old_series.length; i++) {
        var data = old_series[i]["data"];
        var lastData = data[data.length - 1];
        data.push(lastData);
    }
    this.chart.setOption({
        xAxis: {
            data: old_xAxis
        },
        series: old_series
    })
}
// 修改每列的正确数据（存在就替换值，不存在就添加系列series）
function correctOneDataOfSeries(obj, old_series) {
    var old_series = old_series; //当前y轴所有系列
    for (var k in obj) {
        var index = is_in_array_kv(old_series, "name", k, "rtindex");
        // 不存在 就 添加
        if (index === false) {
            var oneData = getNewZeroValSeries();    // 创建一条有完整数据结构的系列
            oneData.pop();
            oneData.push(obj[k]);
            old_series.push({ name: k, data: oneData, type: "line" });
        }
        // 存在 就 替换
        else {
            old_series[index]["data"].pop();
            old_series[index]["data"].push(obj[k]);
        }
    }
    this.chart.setOption({
        series: old_series
    })
}
// 创建一条有完整数据结构的系列
function getNewZeroValSeries(old_xAxis) {
    var old_xAxis = old_xAxis;  //当前x轴数据
    var rtArray = [];
    for (var i = 0; i < old_xAxis.length; i++) {
        rtArray.push(0);
    }
    return rtArray;
}